#ifndef _FONTMANAGER_H_ 
#define	_FONTMANAGER_H_

#include "common.h"

namespace nsFont
{
	enum eFontWeight
	{
		F_FW_DONTCARE = 0,
		F_FW_THIN = 100,
		F_FW_EXTRALIGHT = 200,
		F_FW_LIGHT = 300,
		F_FW_NORMAL = 400,
		F_FW_MEDIUM = 500,
		F_FW_SEMIBOLD = 600,
		F_FW_BOLD = 700,
		F_FW_EXTRABOLD = 800,
		F_FW_HEAVY = 900,
		F_FW_ULTRALIGHT = FW_EXTRALIGHT,
		F_FW_REGULAR = FW_NORMAL,
		F_FW_DEMIBOLD = FW_SEMIBOLD,
		F_FW_ULTRABOLD = FW_EXTRABOLD,
		F_FW_BLACK = FW_HEAVY
	};
	enum eFontCharSet
	{
		F_ANSI_CHARSET  = 0,
		F_DEFAULT_CHARSET = 1,
		F_SYMBOL_CHARSET = 2,
		F_SHIFTJIS_CHARSET = 128,
		F_HANGEUL_CHARSET = 129,
		F_HANGUL_CHARSET = 129,
		F_GB2312_CHARSET = 134,
		F_CHINESEBIG5_CHARSET = 136,
		F_OEM_CHARSET = 255,
		// Beyond this point, only if Windows >= XP
		F_JOHAB_CHARSET = 130,
		F_HEBREW_CHARSET = 177,
		F_ARABIC_CHARSET = 178,
		F_GREEK_CHARSET = 161,
		F_TURKISH_CHARSET = 162,
		F_VIETNAMESE_CHARSET = 163,
		F_THAI_CHARSET = 222,
		F_EASTEUROPE_CHARSET = 238,
		F_RUSSIAN_CHARSET = 204,
		F_MAC_CHARSET = 77,
		F_BALTIC_CHARSET = 186,
		F_FS_LATIN1 = 0x00000001L,
		F_FS_LATIN2 = 0x00000002L,
		F_FS_CYRILLIC = 0x00000004L,
		F_FS_GREEK = 0x00000008L,
		F_FS_TURKISH = 0x00000010L,
		F_FS_HEBREW = 0x00000020L,
		F_FS_ARABIC = 0x00000040L,
		F_FS_BALTIC = 0x00000080L,
		F_FS_VIETNAMESE = 0x00000100L,
		F_FS_THAI = 0x00010000L,
		F_FS_JISJAPAN = 0x00020000L,
		F_FS_CHINESESIMP = 0x00040000L,
		F_FS_WANSUNG = 0x00080000L,
		F_FS_CHINESETRAD = 0x00100000L,
		F_FS_JOHAB = 0x00200000L,
		F_FS_SYMBOL = 0x80000000L
	};
	enum eFontPrecision
	{
		F_OUT_DEFAULT_PRECIS = 0,
		F_OUT_STRING_PRECIS = 1,
		F_OUT_CHARACTER_PRECIS = 2,
		F_OUT_STROKE_PRECIS  = 3,
		F_OUT_TT_PRECIS = 4,
		F_OUT_DEVICE_PRECIS = 5,
		F_OUT_RASTER_PRECIS = 6,
		F_OUT_TT_ONLY_PRECIS = 7,
		F_OUT_OUTLINE_PRECIS = 8,
		F_OUT_SCREEN_OUTLINE_PRECIS = 9,
		F_OUT_PS_ONLY_PRECIS = 10,
		F_CLIP_DEFAULT_PRECIS = 0,
		F_CLIP_CHARACTER_PRECIS = 1,
		F_CLIP_STROKE_PRECIS = 2,
		F_CLIP_MASK = 15,
		F_CLIP_LH_ANGLES = 16,
		F_CLIP_TT_ALWAYS = 32
	};
	enum eFontQuality
	{
		F_DEFAULT_QUALITY = 0,
		F_DRAFT_QUALITY = 1,
		F_PROOF_QUALITY = 2,
		F_NONANTIALIASED_QUALITY = 3,
		F_ANTIALIASED_QUALITY = 4,
		F_CLEARTYPE_QUALITY = 5,
		F_CLEARTYPE_NATURAL_QUALITY = 6
	};
	enum eFontPitch
	{
		F_DEFAULT_PITCH = 0,
		F_FIXED_PITCH = 1,
		F_VARIABLE_PITCH = 2,
		F_MONO_FONT = 8
	};
	enum eFontFamily
	{
		F_FF_DONTCARE = 0,			// Don't care or don't know.
		F_FF_ROMAN = 16,			// Variable stroke width, serifed.
									// Times Roman, Century Schoolbook, etc.
		F_FF_SWISS = 32,			// Variable stroke width, sans-serifed.
									// Helvetica, Swiss, etc.
		F_FF_MODERN = 48,			// Constant stroke width, serifed or sans-serifed.
									// Pica, Elite, Courier, etc.
		F_FF_SCRIPT = 64,			// Cursive, etc.
		F_FF_DECORATIVE = 80		// Old English, etc.
	};
	enum eFontTextFormats
	{
		F_DT_TOP = 0x00000000,
		F_DT_LEFT = 0x00000000,
		F_DT_CENTER = 0x00000001,
		F_DT_RIGHT = 0x00000002,
		F_DT_VCENTER = 0x00000004,
		F_DT_BOTTOM = 0x00000008,
		F_DT_WORDBREAK = 0x00000010,
		F_DT_SINGLELINE = 0x00000020,
		F_DT_EXPANDTABS = 0x00000040,
		F_DT_TABSTOP = 0x00000080,
		F_DT_NOCLIP = 0x00000100,
		F_DT_EXTERNALLEADING = 0x00000200,
		F_DT_CALCRECT = 0x00000400,
		F_DT_NOPREFIX = 0x00000800,
		F_DT_INTERNAL = 0x00001000,
		F_DT_EDITCONTROL = 0x00002000,
		F_DT_PATH_ELLIPSIS = 0x00004000,
		F_DT_END_ELLIPSIS = 0x00008000,
		F_DT_MODIFYSTRING = 0x00010000,
		F_DT_RTLREADING = 0x00020000,
		F_DT_WORD_ELLIPSIS = 0x00040000,
		F_DT_NOFULLWIDTHCHARBREAK = 0x00080000,
		F_DT_HIDEPREFIX = 0x00100000,
		F_DT_PREFIXONLY = 0x00200000
	};
}

#define EFontWeight		nsFont::eFontWeight
#define EFontCharSet	nsFont::eFontCharSet
#define EFontPrecision	nsFont::eFontPrecision
#define EFontQuality	nsFont::eFontQuality
#define EFontPitch		nsFont::eFontPitch
#define EFontFamiy		nsFont::eFontFamily

struct tFont
{
	ID3DXFont* m_pFont;
	PhAssetID m_phID;
	string m_szFaceName;
	PhUInt8 m_phHeight;
	PhUInt8 m_phWidth;
	EFontWeight m_eWeight;
	PhUInt8 m_phMipLevel;
	bool m_bItalics;
	EFontCharSet m_eCharSet;
	EFontPrecision m_ePrecision;
	EFontQuality m_eQuality;
	EFontPitch m_ePitch;
	EFontFamiy m_eFamily;
};

struct tQueuedText
{
	bool m_bAlive;
	//ID3DXSprite* pSprite
	//	A pointer to a ID3DXSprite interface. Used for advanced batching and optimization. Set it to NULL for now.
	string m_szText;
	//	The string you want to render.
	PhInt m_phCount;
	//	The number of characters you want to render. If you want to render the entire string, and the string is NULL terminated, you can just pass -1.
	RECT m_rRect;
	//	Formatting and Clipping rectangle. Used to position and format your text.
	bool m_bCalcRect;
	//	If the bottom and right coordinates weren't set, then this will calculate the size of the Rect from the text. Requires 2 DrawText calls, first does not render.
	DWORD m_dwFormat;
	//	Flags to specify text alignment, clipping and many other things.
	D3DCOLOR m_phColor;
	//	Standard 32-bit ARGB colour. Note: The alpha channel is respected for transparency. If you set the alpha to 0 you will not see your text.
};

class CFontManager
{
private:
	
	//////////////////////////////////////////////////////////////////////////
	// Creation Coms
	IDirect3DDevice9*	m_pDev;
	
//	ID3DXFont can't be Managed. Must reload if device is lost.
//	D3DPOOL				m_ePoolType; 

	//////////////////////////////////////////////////////////////////////////
	// Utilities
	bool										m_bInitialized;
	map<PhAssetID, tFont>						m_pFonts;
	map<PhAssetID, tQueuedText>					m_pQueuedText;
	ID3DXSprite*								m_pFontSurface;
	string										m_szDebug;
	HRESULT										m_hrError;
	
	CFontManager(void);
	~CFontManager(void);
	CFontManager(const CFontManager&){}
	CFontManager& operator=(const CFontManager&){}

public:
	
	bool Initialize(IDirect3DDevice9* _pDev);
	bool Shutdown(void);
	bool Reload(void);

	static CFontManager* GetInstance(void);

	//////////////////////////////////////////////////////////////////////////
	//	FaceName
	// 		The name of the font. If set to an empty string (""), system will pick a font that matches the other parameters.
	// 	Height
	// 		The height (in pixels) of the font you want to create.
	// 	Width
	// 		The width (in pixels) of the font you want to create. Set this to 0 for default width based on the height you gave above.
	// 	Weight
	// 		How thick the font is. Valid values range from 0-1,000.
	//	MipLevels
	// 		Number of MipMaps to create. 0 creates a full chain. Used to show the font at different sizes more efficiently. If not scaling text, use 1 to save memory.
	//	Italic
	// 		True/False, do you want Italics?
	//	CharSet
	// 		Character Set. Used to specify international character sets (Arabic, Greek, etc).
	//	OutputPrecision
	// 		How precisely the output must match the font.
	//	Quality
	// 		Some possible values are: ANTIALIASED_QUALITY, DEFAULT_QUALITY, DRAFT_QUALITY, and PROOF_QUALITY.
	//	PitchAndFamily
	// 		You can safely set this to DEFAULT_PITCH|FF_DONTCARE.
	PhAssetID AddFont(string _szFaceName = "Arial", 
				PhUInt8 _phHeight = 32,
				PhUInt8 _phWidth = 0,
				EFontWeight _eWeight = nsFont::F_FW_NORMAL, 
				PhUInt8 _phMipLevel = 1, 
				bool _bItalics = false,
				EFontCharSet _eCharSet = nsFont::F_DEFAULT_CHARSET,
				EFontPrecision _ePrecision = nsFont::F_OUT_DEFAULT_PRECIS, 
				EFontQuality _eQuality = nsFont::F_DEFAULT_QUALITY, 
				EFontPitch _ePitch = nsFont::F_DEFAULT_PITCH, 
				EFontFamiy _eFamily = nsFont::F_FF_DONTCARE);

	ID3DXFont* GetFont(PhAssetID _phID);

	PH_INLINE ID3DXSprite* GetSpriteSurface(void) { return (m_pFontSurface) ? m_pFontSurface : NULL; }

	bool QueueText(string _szText = "", PhInt _phCount = -1, float _fTop = 0.0f, float _fLeft = 0.0f, float _fBottom = 0.0f, float _fRight = 0.0f, DWORD _dwFormat = DT_LEFT|DT_NOCLIP, D3DCOLOR _Color = 0xffffffff);
	tQueuedText* GetQueuedText(void);
};

#endif